﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using VAdvantage.Model;
using VAdvantage.Logging;
using VAdvantage.Utility;
using System.Data;
using VAdvantage.DataBase;
using System.Text;

namespace VAdvantage.Dialogs
{
    public partial class RecordAccessDialog : ChildWindow
    {
        #region Private Varibales
        private static long serialVersionUID = -5208621373205009190L;
        private int _AD_Table_ID;
        private int _Record_ID;
        private List<MRecordAccess> _recordAccesss = new List<MRecordAccess>();
        private int _currentRow = 0;
        private MRecordAccess _currentData = null;
        private VLogger log = VLogger.GetVLogger(typeof(RecordAccessDialog).FullName);

        #endregion

        /// <summary>
        /// Default constructor
        /// </summary>
        public RecordAccessDialog()
        {
            InitializeComponent();
        }

        /// <summary>
        /// Record Access Dialog
        /// </summary>
        /// <param name="owner"></param>
        /// <param name="AD_Table_ID"></param>
        /// <param name="Record_ID"></param>
        public RecordAccessDialog(int AD_Table_ID, int Record_ID)
            : this()
        {
            // log.Info("AD_Table_ID=" + AD_Table_ID + ", Record_ID=" + Record_ID);
            _AD_Table_ID = AD_Table_ID;
            _Record_ID = Record_ID;
            try
            {
                System.Threading.ThreadPool.QueueUserWorkItem(delegate
                {
                    DynInit();
                    // Deployment.Current.Dispatcher.BeginInvoke(() => Show());
                });

            }
            catch (Exception e)
            {
                log.Log(Level.SEVERE, "", e);
            }
        }

        private void Show(IDataReader idrRole, string role, string active, string exclude, string read, string dependent)
        {

            RunTimeText(role, active, exclude, read, dependent);
            //load role combo box
            while (idrRole.Read())
            {
                cmbRole.Items.Add(new KeyNamePair(Util.GetValueOfInt(idrRole[0]), Util.GetValueOfString(idrRole[1])));
            }
            SetLine(0, false);
            this.Show();

        }

        /// <summary>
        /// Run time text
        /// </summary>
        private void RunTimeText(string role, string active, string exclude, string read, string dependent)
        {
            lblRole.Content = role;
            chkActive.Content = active;
            chkExclude.Content = exclude;
            chkReadOnly.Content = read;
            chkDependent.Content = dependent;
        }

        /// <summary>
        /// Dynamic Init
        /// </summary>
        private void DynInit()
        {
            //	Load Roles
            String sqlRole = MRole.GetDefault().AddAccessSQL(
                "SELECT AD_Role_ID, Name FROM AD_Role ORDER BY 2",
                "AD_Role", MRole.SQL_NOTQUALIFIED, MRole.SQL_RO);


            //	Load Record Access for all roles
            string sql = "SELECT * FROM AD_Record_Access "
                 + "WHERE AD_Table_ID=" + _AD_Table_ID + " AND Record_ID=" + _Record_ID + " AND AD_Client_ID=" + Envs.GetCtx().GetAD_Client_ID();
            IDataReader idr = null;
            IDataReader idrRole = null;
            try
            {
                idr = DB.ExecuteReader(sql);
                idrRole = DB.ExecuteReader(sqlRole);
                while (idr.Read())
                {
                    _recordAccesss.Add(new MRecordAccess(Envs.GetCtx(), idr, null));
                }
                idr.Close();
            }
            catch (Exception e)
            {
                if (idr != null)
                {
                    idr.Close();
                    idr = null;
                }
                log.Log(Level.SEVERE, sql, e);
            }

            log.Fine("#" + _recordAccesss.Count);
            // SetLine(0, false);



            string role = Msg.Translate(Envs.GetCtx(), "AD_Role_ID");
            string active = Msg.Translate(Envs.GetCtx(), "IsActive");
            string exclude = Msg.Translate(Envs.GetCtx(), "IsExclude");
            string read = Msg.Translate(Envs.GetCtx(), "IsReadOnly");
            string dependent = Msg.Translate(Envs.GetCtx(), "IsDependentEntities");
            Deployment.Current.Dispatcher.BeginInvoke(() => Show(idrRole, role, active, exclude, read, dependent));
        }

        /// <summary>
        /// Set Line
        /// </summary>
        /// <param name="rowDelta">rowDelta delta to current row</param>
        /// <param name="newRecord">newRecord new</param>
        private void SetLine(int rowDelta, bool newRecord)
        {
            log.Fine("delta=" + rowDelta + ", new=" + newRecord
                + " - currentRow=" + _currentRow + ", size=" + _recordAccesss.Count);
            int maxIndex = 0;
            //	nothing defined
            if (_recordAccesss.Count == 0)
            {
                _currentRow = 0;
                maxIndex = 0;
                newRecord = true;
                SetLine(null);
            }
            else if (newRecord)
            {
                _currentRow = _recordAccesss.Count;
                maxIndex = _currentRow;
                SetLine(null);
            }
            else
            {
                _currentRow += rowDelta;
                maxIndex = _recordAccesss.Count - 1;
                if (_currentRow < 0)
                    _currentRow = 0;
                else if (_currentRow > maxIndex)
                    _currentRow = maxIndex;
                //
                MRecordAccess ra = (MRecordAccess)_recordAccesss[_currentRow];
                SetLine(ra);
            }
            //	Label
            StringBuilder txt = new StringBuilder();
            if (newRecord)
            {
                txt.Append("+");
            }
            txt.Append(_currentRow + 1).Append("/").Append(maxIndex + 1);

            lblCount.Content = txt.ToString();

            //	set up/down
            btnUp.IsEnabled = _currentRow > 0;
            btnDown.IsEnabled = _currentRow < maxIndex;
        }

        /// <summary>
        /// Set Selection
        /// </summary>
        /// <param name="ra">record access</param>
        private void SetLine(MRecordAccess ra)
        {
            int AD_Role_ID = 0;
            bool active = true;
            bool exclude = true;
            bool isReadonly = false;
            bool dependent = false;
            //
            if (ra != null)
            {
                AD_Role_ID = ra.GetAD_Role_ID();
                active = ra.IsActive();
                exclude = ra.IsExclude();
                isReadonly = ra.IsReadOnly();
                dependent = ra.IsDependentEntities();
            }
            chkActive.IsChecked = active;
            chkExclude.IsChecked = exclude;
            chkReadOnly.IsChecked = isReadonly;
            chkDependent.IsChecked = dependent;
            btnDelete.IsEnabled = (ra != null);
            //
            KeyNamePair selection = null;
            for (int i = 0; i < cmbRole.Items.Count; i++)
            {
                KeyNamePair pp = (KeyNamePair)cmbRole.Items[i];
                if (pp.GetKey() == AD_Role_ID)
                {
                    selection = pp;
                }
            }
            if (selection != null && ra != null)
            {
                cmbRole.SelectedItem = selection;
                _currentData = ra;
                log.Fine("" + ra);
            }
            else
            {
                _currentData = null;
            }
        }

        /// <summary>
        /// Save Command
        /// </summary>
        /// <returns>true if saved</returns>
        private bool Cmd_Save()
        {
            KeyNamePair pp = (KeyNamePair)cmbRole.SelectedItem;
            cmbRole.SetBackGround(pp == null);
            if (pp == null)
            {
                return false;
            }
            int AD_Role_ID = pp.GetKey();
            //
            bool isActive = Util.GetValueOfBool(chkActive.IsChecked);
            bool isExclude = Util.GetValueOfBool(chkExclude.IsChecked);
            bool isReadOnly = Util.GetValueOfBool(chkReadOnly.IsChecked);
            bool isDependentEntities = Util.GetValueOfBool(chkDependent.IsChecked);

            System.Threading.ThreadPool.QueueUserWorkItem(delegate
                {
                    if (_currentData == null)
                    {
                        _currentData = new MRecordAccess(Envs.GetCtx(), AD_Role_ID, _AD_Table_ID, _Record_ID, null);
                        _recordAccesss.Add(_currentData);
                        _currentRow = _recordAccesss.Count - 1;
                    }
                    if (_currentData != null)
                    {
                        _currentData.SetIsActive(isActive);
                        _currentData.SetIsExclude(isExclude);
                        _currentData.SetIsReadOnly(isReadOnly);
                        _currentData.SetIsDependentEntities(isDependentEntities);
                    }
                    bool success = _currentData.Save();
                    log.Fine("Success=" + success);
                    Deployment.Current.Dispatcher.BeginInvoke(() => ReturnValue(success));
                });
            return true;
        }

        private bool ReturnValue( bool success)
        {
            if (!success)
            {
                return false;
            }
            return (bool)(this.DialogResult = true);
        }

        /// <summary>
        /// Delete Command
        /// </summary>
        /// <returns>true if deleted</returns>
        private void Cmd_Delete()
        {
            bool success = false;
            if (_currentData == null)
            {
                log.Log(Level.SEVERE, "No data");
            }
            else
            {
                System.Threading.ThreadPool.QueueUserWorkItem(delegate
                  {
                      success = _currentData.Delete(true);
                      _currentData = null;
                      _recordAccesss.Remove(_currentData);
                      log.Fine("Success=" + success);
                  });
            }
        }

        private void btnOk_Click(object sender, RoutedEventArgs e)
        {
            Cmd_Save();
        }

        private void btnCancel_Click(object sender, RoutedEventArgs e)
        {
            this.DialogResult = false;
        }

        private void btnDown_Click(object sender, RoutedEventArgs e)
        {
            SetLine(+1, false);
        }

        private void btnUp_Click(object sender, RoutedEventArgs e)
        {
            SetLine(-1, false);
        }

        private void btnDelete_Click(object sender, RoutedEventArgs e)
        {
            Cmd_Delete();
        }

        private void btnNew_Click(object sender, RoutedEventArgs e)
        {
            SetLine(0, true);
        }
    }
}

